//package org.wheel.runner;
//
//import cn.hutool.core.util.StrUtil;
//import cn.hutool.log.Log;
//import cn.hutool.log.LogFactory;
//import org.springframework.beans.BeansException;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.beans.factory.config.BeanDefinition;
//import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
//import org.springframework.beans.factory.support.BeanDefinitionRegistry;
//import org.springframework.boot.ApplicationArguments;
//import org.springframework.boot.ApplicationRunner;
//import org.springframework.boot.autoconfigure.SpringBootApplication;
//import org.springframework.context.ApplicationContext;
//import org.springframework.context.ConfigurableApplicationContext;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.ComponentScan;
//import org.springframework.core.env.Environment;
//import org.springframework.core.io.ResourceLoader;
//import org.wheel.plugins.starter.autoconfigure.DynamicDataSourceProperties;
//import org.wheel.plugins.starter.jdbc.pool.config.CustomClassPathScanningCandidateComponentProvider;
//import org.wheel.plugins.starter.jdbc.pool.config.DaoConfigProperties;
//import org.wheel.plugins.starter.jdbc.pool.config.DaoFactory;
//import org.wheel.plugins.starter.jdbc.pool.config.XmlMapperLoader;
//import org.wheel.plugins.starter.jdbc.pool.dao.BaseDaoProxy;
//import org.wheel.plugins.starter.jdbc.pool.dao.IBaseDao;
//
//import java.util.ArrayList;
//import java.util.Arrays;
//import java.util.List;
//import java.util.Set;
//
////@Order(1)
////@AutoConfigureAfter({DynamicDataSourceProperties.class, DaoConfigProperties.class})
//public class DaoProxyRunner implements ApplicationRunner {
//
//    // 直接使用 LogFactory 创建日志对象，Hutool 会自动检测项目中的日志框架（优先级：Slf4j > Log4j > Logback > JDK Logging）
//    private static final Log log = LogFactory.get();
//
//    @Autowired
//    private Environment environment;
//    private String[] basePackages;
//
//    @Bean
//    public XmlMapperLoader xmlMapperLoader(DaoConfigProperties daoConfigProperties, ResourceLoader resourceLoader) {
//        return new XmlMapperLoader(daoConfigProperties, resourceLoader);
//    }
//
//    @Bean
//    public DaoFactory baseDaoFactory(DaoConfigProperties daoConfigProperties, DynamicDataSourceProperties dynamicDataSourceProperties,
//                                     XmlMapperLoader xmlMapperLoader) {
//        return new DaoFactory(daoConfigProperties, xmlMapperLoader, dynamicDataSourceProperties);
//    }
//
//    @Bean
//    public BaseDaoProxy baseDaoProxy(DaoFactory baseDaoFactory) {
//        return new BaseDaoProxy(baseDaoFactory);
//    }
//
//
////    @Autowired
////    private BeanDefinitionRegistry registry;
//    @Autowired
//    private ApplicationContext applicationContext;
//
//    @Override
//    public void run(ApplicationArguments args) throws Exception {
//        log.info("开始加载 BaseDaoFactory 和 BaseDaoProxy...");
//        postProcessBeanDefinitionRegistry();
//    }
//
//    /**
//     * 获取启动类
//     * @return 启动类
//     */
//    private Class<?> getStartupClass() {
//        // 获取所有 Bean 的定义
//        String[] beanNames = applicationContext.getBeanDefinitionNames();
//        for (String beanName : beanNames) {
//            Class<?> beanClass = applicationContext.getType(beanName);
//            if (beanClass != null && beanClass.isAnnotationPresent(SpringBootApplication.class)) {
//                return beanClass;
//            }
//        }
//        return null;
//    }
//
////    @Override
//    public void postProcessBeanDefinitionRegistry() throws BeansException {
//        log.info("开始加载和合并YAML配置文件...");
//
////        YamlConfigLoader loader = new YamlConfigLoader(this.environment);
////        try {
////            // 步骤1：合并所有相关配置文件
////            Properties mergedConfig = loader.mergeAllYamlConfigs();
////
////            // 步骤2：添加到环境并绑定配置类
////            loader.bindAndRegisterConfigurationBeans(registry, mergedConfig);
////
////            log.info("YAML配置加载完成，共合并 {} 个配置项", mergedConfig.size());
////        }catch (IOException e){
////            log.error("YAML配置加载失败", e);
////        }
//
//        BaseDaoProxy baseDaoProxy = applicationContext.getBean(BaseDaoProxy.class);
//        // 步骤1：综合获取配置信息
//        resolveScanConfiguration();
//
//        // 步骤2：执行扫描和注册
//        performDaoRegistration(baseDaoProxy);
//    }
//
//    /**
//     * 综合解析扫描配置
//     */
//    private void resolveScanConfiguration() {
//        List<String> allPackages = new ArrayList<>();
//
//        // 1. 从启动类注解获取
//        String startupClass = findStartupClass();
//        if (startupClass != null) {
//            extractPackagesFromStartupClass(startupClass, allPackages);
//        }
//
//        // 2. 从 Environment 获取配置
//        extractPackagesFromEnvironment(allPackages);
//
//        // 3. 从系统属性获取（备用）
////        extractPackagesFromSystemProperties(allPackages);
//
//        // 转换为数组
//        this.basePackages = allPackages.stream().map(StrUtil::trim).distinct().toArray(String[]::new);
//
//        log.debug("最终扫描包路径: " + Arrays.toString(basePackages));
//    }
//
//    /**
//     * 从启动类提取包配置
//     */
//    private void extractPackagesFromStartupClass(String startupClassName, List<String> packageList) {
//        try {
//            Class<?> startupClass = Class.forName(startupClassName);
//
//            // 检查启动类上的自定义注解
//            if (startupClass.isAnnotationPresent(SpringBootApplication.class)) {
//                SpringBootApplication annotation = startupClass.getAnnotation(SpringBootApplication.class);
//
//                // 获取 basePackages
//                if (annotation.scanBasePackages().length > 0) {
//                    packageList.addAll(Arrays.asList(annotation.scanBasePackages()));
//                }
//                // 获取 ComponentScan
//                ComponentScan scan = startupClass.getAnnotation(ComponentScan.class);
//                if(scan!=null && scan.basePackages().length > 0){
//                    packageList.addAll(Arrays.asList(scan.basePackages()));
//                }
//
//                // 如果没有显式配置包路径，使用启动类所在的包
//                if (packageList.isEmpty()) {
//                    packageList.add(startupClass.getPackage().getName());
//                }
//            }
//        } catch(ClassNotFoundException e){
//            System.err.println("无法解析启动类注解: " + startupClassName);
//        }
//    }
//
//    /**
//     * 从 Environment 提取包配置
//     */
//    private void extractPackagesFromEnvironment(List<String> packageList) {
//        // 从 application.properties/yml 获取配置
//        String packagesFromProps = environment.getProperty("system.default.dao.dao-scan-packages");
//        if (packagesFromProps != null) {
//            packageList.addAll(Arrays.asList(packagesFromProps.split(",")));
//        }
//
//        // 从配置类前缀获取
//        String packagesFromConfig = environment.getProperty("system.default.dao.dao-scan-packages");
//        if (packagesFromConfig != null) {
//            packageList.addAll(Arrays.asList(packagesFromConfig.split(",")));
//        }
//    }
//
//    /**
//     * 执行 DAO 扫描和注册
//     */
//    private void performDaoRegistration(BaseDaoProxy baseDaoProxy) {
//        if (basePackages == null || basePackages.length == 0) {
//            throw new IllegalStateException("未找到有效的DAO扫描包路径配置");
//        }
//        baseDaos(baseDaoProxy);
//    }
//
//
//    // 动态注册所有继承了 BaseDao<T> 的接口
//    public void baseDaos(BaseDaoProxy baseDaoProxy) {
//        ConfigurableApplicationContext configurableApplicationContext = (ConfigurableApplicationContext) applicationContext;
//        ConfigurableListableBeanFactory beanFactory = configurableApplicationContext.getBeanFactory();
//
//        // 获取当前类所在的包下的所有类
//        String basePackage = String.join(",", this.basePackages);
//
//        // 添加注解过滤器
//        CustomClassPathScanningCandidateComponentProvider scanner = new CustomClassPathScanningCandidateComponentProvider((BeanDefinitionRegistry) beanFactory);
//        try {
//            Set<BeanDefinition> candidateComponents = scanner.findCandidateComponents(basePackage);
//            for (BeanDefinition candidateComponent : candidateComponents) {
//                Class<?> daoInterface = Class.forName(candidateComponent.getBeanClassName());
//                if (daoInterface.isInterface() && IBaseDao.class.isAssignableFrom(daoInterface)) {
////                    log.info("正在注册BaseDao实例：{}（接口：{}）", daoInterface.getSimpleName(), daoInterface.getName());
////                    BaseDao<?> baseDao = baseDaoProxy.getBaseDao(daoInterface, baseDaoFactory);
////                    if(baseDao != null) {
////                        SingletonBeanRegistry singletonRegistry = (SingletonBeanRegistry) registry;
////                        String beanName = StrUtil.lowerFirst(daoInterface.getSimpleName()); // Bean名称：接口名首字母小写（如`userDao`）
////                        if(!singletonRegistry.containsSingleton(beanName)) {
////                            singletonRegistry.registerSingleton(beanName, baseDao);
////                            // 日志：确认注册成功
////                            System.out.println("注册BaseDao实例：" + beanName + "（接口：" + daoInterface.getName() + "）");
////                        }
////                    }else{
////                        log.error("无法注册BaseDao实例：{}（接口：{}）", daoInterface.getSimpleName(), daoInterface.getName());
////                    }
//
//
//                    log.debug("正在注册BaseDao实例：{}（接口：{}）", daoInterface.getSimpleName(), daoInterface.getName());
//                    String beanName = StrUtil.lowerFirst(daoInterface.getSimpleName());
//                    IBaseDao<?> IBaseDao = baseDaoProxy.getBaseDao(daoInterface);
//                    beanFactory.registerSingleton(beanName, IBaseDao);
//                    log.debug("注册BaseDao实例：" + beanName + "（接口：" + daoInterface.getName() + "）");
//                }
//            }
//        } catch (ClassNotFoundException e) {
////            e.printStackTrace();
//            log.error("扫描dao层包的时候错误", e);
//        }
//    }
//
//    /**
//     * 查找启动类（带 @SpringBootApplication 注解的类）
//     */
//    private String findStartupClass() {
//        Class<?> startup = getStartupClass();
//        if(startup != null){
//            return startup.getName();
//        }
//        return null;
//    }
//}